﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Caching;
using System.Web;

namespace SuggestionService
{
    public class SimilarGroupCalculator
    {
        private const int ZeroScore = 25;
       
        private static double CalculateSimilarityScore(string userId, string otherUserId)
        {   
            //Getting quizes scores for current user
            var currentUserScores = DataAccess.GetQuizesTakenByUser(userId).Select(t => ConvertScoresToPercents(t.Scores, t.MaxScores)).ToArray();
            //Getting quizes scores for other user
            var otherUserScores = DataAccess.GetQuizesTakenByUser(otherUserId).Select(t => ConvertScoresToPercents(t.Scores, t.MaxScores)).ToArray();
            //Calculating similarity score between two users
            var similarityScore = DistanceCalculator.CalculateEuclidian(currentUserScores, otherUserScores);
            return similarityScore;
        }

        public static int ConvertScoresToPercents(double scores, double max)
        {
            if (scores == 0)
                return ZeroScore;
            return (int)((scores/max)*100);
        }

        private static Dictionary<string, double> CalculateSimilarityScores(string userId, int groupCount)
        {
            var simScoreDictionary = new Dictionary<string, double>();
            //Getting all users
            var allUsers = DataAccess.GetAllUsersExcept(userId);
            //Finding similat scores
            for (int i = 0; i < allUsers.Count; i++)
            {
                var simScore = CalculateSimilarityScore(userId, allUsers[i].UserId);
                simScoreDictionary.Add(allUsers[i].UserId, simScore);
            }
          
            return simScoreDictionary;
        }
       
        public static List<SimilarUser> FindSimilarityGroup(string userId, int groupCount)
        {
            //Ranking similar users
            var similarityScores = CalculateSimilarityScores(userId, groupCount);
            var similarUsers = similarityScores.OrderByDescending(u => u.Value).Take(groupCount);
            //Returning similar group
            return similarUsers.Select(similarUser => new SimilarUser
                                                          {
                                                              SimilarityScore = similarUser.Value, 
                                                              User = new User {UserId = similarUser.Key}
                                                          }).ToList();
        }
    }
}